package com.huize.ladon.apm.common.util;

import com.huize.ladon.apm.common.common.PairKV;
import com.huize.ladon.apm.common.constant.CommonConstants;
import org.apache.commons.lang3.StringUtils;

import java.lang.management.ManagementFactory;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

import static com.huize.ladon.apm.common.constant.CommonConstants.METHOD_SIGNATURE_CHAR;
import static com.huize.ladon.apm.common.constant.CommonConstants.METHOD_SPLIT_CHAR;
import static com.huize.ladon.apm.common.constant.Constants.IP_SPLIT_CHAR;

/**
 * 公共Utils 大杂烩
 *
 * @author hz15051315
 * @date 2019年3月7日 下午2:14:02
 */
@SuppressWarnings("unchecked")
public final class CommonUtils {

    public static URL getResource(String relativePath) {
        return Thread.currentThread().getContextClassLoader().getResource(relativePath);
    }

    /**
     * 组合RouteKey
     *
     * @param agentId
     * @param hostIp
     * @return
     */
    public static String buildRouteKey(final String agentId, final String hostIp) {
        return agentId + "_" + hostIp;
    }

    /**
     * 截取字符串
     *
     * @param str
     * @param separator
     * @return
     */
    public static PairKV<String, String> substringAfterLast(final String str, final String separator) {
        if (StringUtils.isBlank(str)) {
            return new PairKV(str, null);
        }

        final int lastIndex = str.lastIndexOf(separator);
        String right = StringUtils.EMPTY;
        String left = StringUtils.EMPTY;

        if (lastIndex > 0) {
            left = str.substring(0, lastIndex);
            right = str.substring(lastIndex + separator.length());
        } else {
            right = str;
        }
        return new PairKV(left, right); //PairKV.right(left, right);
    }

    /**
     * 格式化调用接口路径
     *
     * @param tag
     * @return
     */
    public static String formatMethodTag(String tag) {
        if (StringUtils.isBlank(tag) || tag.indexOf(".") < 1) {
            return tag;
        }

        String[] tmp = tag.split(IP_SPLIT_CHAR);
        if (tmp.length < 5) {
            return tag;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < tmp.length; i++) {
            if (i > (tmp.length - 3)) {
                break;
            }
            sb.append(tmp[i].substring(0, 1)).append(".");
        }

        sb.append(tmp[tmp.length - 2]).append(".").append(tmp[tmp.length - 1]);
        return sb.toString();
    }

    /**
     * 格式化FullPath
     *
     * @param fullPath
     * @param paramNum
     * @return
     */
    public static String formatFullPath(String fullPath, String paramNum) {
        int length = MixAllUtils.parseInteger(paramNum);
        return formatFullPath(fullPath, length);
    }

    /**
     * 格式化FullPath
     *
     * @param fullPath
     * @param paramNum
     * @return
     */
    public static String formatFullPath(String fullPath, int paramNum) {
        if (MixAllUtils.isEmpty(fullPath)) {
            return "";
        }
        if (fullPath.contains("#")) {
            return fullPath;
        }
        if (fullPath.length() > CommonConstants.INTERFACE_FULL_PATH_MAX_LENGTH) {
            return fullPath.substring(0, CommonConstants.INTERFACE_FULL_PATH_MAX_LENGTH);
        }
        String value = paramNum > 0 ? (fullPath + "#" + paramNum) : fullPath;
        return value;
    }

    /**
     * 去除方法签名末尾的#符号 <br/>
     * 例如从 com.huize.framework.catfish.examples.api.facade.HelloFacade.hello#1 解析 com.huize.framework.catfish.examples.api.facade.HelloFacade.hello
     *
     * @param tag
     * @return
     */
    public static String resolveFullPath(String tag) {
        if (StringUtils.isBlank(tag) || tag.equalsIgnoreCase(METHOD_SIGNATURE_CHAR)) {
            return null;
        }

        int index = tag.lastIndexOf(METHOD_SIGNATURE_CHAR);
        String fullPath = index >= 0 ? tag.substring(0, index) : tag;
        return fullPath;
    }

    /**
     * 解析方法名 <br/>
     * 例如从 com.huize.framework.catfish.examples.api.facade.HelloFacade.hello#1 解析 hello
     *
     * @param methodFullPath 接口方法的完整路径
     * @return
     */
    public static String resolveMethodName(String methodFullPath) {
        if (StringUtils.isBlank(methodFullPath) || methodFullPath.equalsIgnoreCase(METHOD_SIGNATURE_CHAR)) {
            return null;
        }

        int index = methodFullPath.lastIndexOf(METHOD_SIGNATURE_CHAR);
        String fullPath = index >= 0 ? methodFullPath.substring(0, index) : methodFullPath;
        String[] values = fullPath.split(METHOD_SPLIT_CHAR);
        if (values == null || values.length < 1) {
            return null;
        }
        return values[values.length - 1];
    }

    /**
     * 解析接口名  <br/>
     * 例如从 com.huize.framework.catfish.examples.api.facade.HelloFacade.hello#1 解析 HelloFacade
     *
     * @param methodFullPath
     * @return
     */
    public static String resolveClazzName(String methodFullPath) {
        if (StringUtils.isBlank(methodFullPath) || methodFullPath.equalsIgnoreCase(METHOD_SIGNATURE_CHAR)) {
            return null;
        }

        int index = methodFullPath.lastIndexOf(METHOD_SIGNATURE_CHAR);
        String fullPath = index >= 0 ? methodFullPath.substring(0, index) : methodFullPath;
        String[] values = fullPath.split(METHOD_SPLIT_CHAR);
        if (values == null || values.length < 2) {
            return null;
        }
        return values[values.length - 2];
    }

    /**
     * 解析参数列表 <br/>
     * 例如从 ["java.lang.String","java.lang.Integer"] 解析 java.lang.String,java.lang.Integer
     *
     * @param paramContent
     * @return
     */
    public static String resolveParamContent(String paramContent) {
        if (StringUtils.isBlank(paramContent) || paramContent.equals("[]") || paramContent.equals("[\"\"]")) {
            return "";
        }

        String value = paramContent.replaceAll("\"", "");
        if (value.startsWith("[")) {
            value = value.substring(1);
        }
        if (value.endsWith("]")) {
            value = value.substring(0, value.length() - 1);
        }
        return value;
    }

    /**
     * 获取进程PID
     *
     * @return
     */
    public static int getPid() {
        String name = ManagementFactory.getRuntimeMXBean().getName();
        String pid = name.split("@")[0];
        if (StringUtils.isBlank(pid) || !isNumeric(pid)) {
            return 0;
        }
        return MixAllUtils.parseInteger(pid);
    }

    /**
     * 校验是否为数字
     *
     * @param value
     * @return
     */
    public static boolean isNumeric(String value) {
        try {
            Long.parseLong(value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否是int型
     *
     * @param input
     * @return
     */
    public static boolean isInt(String input) {
        if (StringUtils.isBlank(input)) {
            return false;
        }

        try {
            Integer.parseInt(input);
            return true;
        } catch (NumberFormatException ex) {
            return false;
        }
    }

    /**
     * 检查字符串中是否是Float型数字
     *
     * @param input
     * @return
     */
    public static boolean isFloat(String input) {
        if (StringUtils.isEmpty(input)) {
            return false;
        }

        try {
            Float.parseFloat(input);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * 获取UUID字符串
     *
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    public static void main(String[] args) {
        String fullPath = "com.huize.framework.catfish.examples.client.facade.RemotingInterface.createInsureNum#0";
        System.out.println(resolveFullPath(fullPath));
        System.out.println(formatMethodTag(fullPath));
        System.out.println(resolveMethodName(fullPath));
        System.out.println(resolveClazzName(fullPath));
        System.out.println();

        String value = "com.huize.framework.catfish.examples.client.facade.RemotingInterface.createInsureNum";
        System.out.println(formatFullPath(value, 2));
    }

}
